"""
Custom Logging Formatters
=========================

Rich console integration and custom formatting for CapsWriter logging.
"""

import logging
from typing import Optional
from rich.console import Console
from rich.logging import RichHandler
from rich.text import Text
from rich.theme import Theme


# Custom theme for logging
LOGGING_THEME = Theme({
    'logging.level.debug': 'cyan',
    'logging.level.info': 'green', 
    'logging.level.warning': 'yellow',
    'logging.level.error': 'red',
    'logging.level.critical': 'bold red',
    'logging.path': 'dim cyan',
    'logging.function': 'dim blue'
})


class RichFormatter(logging.Formatter):
    """
    Custom Rich formatter that integrates with existing console usage.
    Maintains CapsWriter's visual style while adding structured logging.
    """
    
    def __init__(self, 
                 show_time: bool = True,
                 show_path: bool = False,
                 console: Optional[Console] = None):
        super().__init__()
        
        # Use provided console or create new one with CapsWriter theme
        if console is None:
            self.console = Console(
                highlight=False,
                theme=LOGGING_THEME
            )
        else:
            self.console = console
            
        self.show_time = show_time
        self.show_path = show_path
        
        # Level to style mapping
        self.level_styles = {
            'DEBUG': 'logging.level.debug',
            'INFO': 'logging.level.info', 
            'WARNING': 'logging.level.warning',
            'ERROR': 'logging.level.error',
            'CRITICAL': 'logging.level.critical'
        }
    
    def format(self, record: logging.LogRecord) -> str:
        """Format log record with Rich styling."""
        
        # Create styled components
        level_style = self.level_styles.get(record.levelname, 'white')
        
        # Build formatted message parts
        parts = []
        
        if self.show_time:
            time_str = self.formatTime(record, '%H:%M:%S')
            parts.append(f'[dim]{time_str}[/dim]')
        
        # Level with styling
        level_text = f'[{level_style}]{record.levelname:8}[/{level_style}]'
        parts.append(level_text)
        
        # Logger name (shortened for readability)
        logger_name = record.name.replace('capswriter.', '')
        parts.append(f'[logging.path]{logger_name:15}[/logging.path]')
        
        # Function name if showing path details
        if self.show_path:
            parts.append(f'[logging.function]{record.funcName:12}[/logging.function]')
        
        # The actual message
        parts.append(record.getMessage())
        
        # Join all parts
        formatted = ' | '.join(parts)
        
        # Add exception info if present
        if record.exc_info and not record.exc_text:
            record.exc_text = self.formatException(record.exc_info)
        
        if record.exc_text:
            formatted += '\n' + record.exc_text
            
        return formatted


class ConsoleLogHandler(RichHandler):
    """
    Custom Rich handler that works with existing CapsWriter console usage.
    Preserves the visual style while adding logging capabilities.
    """
    
    def __init__(self, console: Optional[Console] = None):
        # Import existing console to maintain consistency
        try:
            from util.server_cosmic import console as server_console
            console = console or server_console
        except ImportError:
            try:
                from util.client_cosmic import console as client_console  
                console = console or client_console
            except ImportError:
                # Fallback to new console with CapsWriter styling
                console = Console(highlight=False, theme=LOGGING_THEME)
        
        super().__init__(
            console=console,
            show_time=True,
            show_path=False,
            enable_link_path=False,
            markup=True
        )
    
    def emit(self, record: logging.LogRecord):
        """Emit log record using Rich console."""
        try:
            # Format message with our custom formatter
            formatter = RichFormatter(
                show_time=True,
                show_path=False,
                console=self.console
            )
            
            formatted_message = formatter.format(record)
            
            # Print using console with appropriate styling
            if record.levelno >= logging.ERROR:
                self.console.print(formatted_message, style='red')
            elif record.levelno >= logging.WARNING:
                self.console.print(formatted_message, style='yellow')
            else:
                self.console.print(formatted_message)
                
        except Exception:
            # Fallback to basic handler if Rich formatting fails
            self.handleError(record)


class PerformanceFormatter(logging.Formatter):
    """
    Special formatter for performance metrics logging.
    Outputs structured data suitable for analysis.
    """
    
    def format(self, record: logging.LogRecord) -> str:
        """Format performance metrics as structured data."""
        
        # Base message
        formatted = super().format(record)
        
        # Add performance metrics if available
        if hasattr(record, 'duration'):
            formatted += f" | Duration: {record.duration:.3f}s"
        
        if hasattr(record, 'memory_usage'):
            formatted += f" | Memory: {record.memory_usage:.1f}MB"
            
        if hasattr(record, 'cpu_percent'):
            formatted += f" | CPU: {record.cpu_percent:.1f}%"
        
        return formatted


class ContextualFormatter(logging.Formatter):
    """
    Formatter that includes contextual information for debugging.
    Adds request IDs, client information, etc.
    """
    
    def format(self, record: logging.LogRecord) -> str:
        """Format with contextual information."""
        
        # Start with base formatting
        formatted = super().format(record)
        
        # Add context if available
        context_parts = []
        
        if hasattr(record, 'client_id'):
            context_parts.append(f"Client:{record.client_id}")
            
        if hasattr(record, 'session_id'):
            context_parts.append(f"Session:{record.session_id}")
            
        if hasattr(record, 'request_id'):
            context_parts.append(f"Request:{record.request_id}")
        
        if context_parts:
            formatted += f" [{' | '.join(context_parts)}]"
        
        return formatted